/**
 * Copyright (c) 2008, Keisuke Inoue, Syracuse Unviersity
 * All rights reserved.
 *
 */
package edu.syr.iis.web.model;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.hibernate.Criteria;
import org.hibernate.FetchMode;
import org.hibernate.Hibernate;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Property;
import org.hibernate.criterion.Restrictions;

import edu.syr.iis.web.util.HibernateUtil;

/**
 * @author kinoue
 *
 */
public class AssignmentManager
{
	public DisagreementMatrix getDisagreementMatrix()
	{
	    Assignment assignment = getAssignment(549);
	    	    
	    DisagreementMatrix matrix = new DisagreementMatrix();
	    Set<DialogueAct> annotationSet = new HashSet<DialogueAct>();
	    
	    matrix.annotator1 = (User) assignment.conversation.getAnnotators().toArray()[0];
	    matrix.annotator2 = (User) assignment.conversation.getAnnotators().toArray()[1];	    
	    
	    for (Message message: assignment.conversation.getMessages())
	    {
		annotationSet.addAll(message.getDialogueActs());
	    }
	    
	    matrix.annotations = new ArrayList<DialogueAct>(annotationSet);	    
	    matrix.matrix = new int[matrix.annotations.size()][matrix.annotations.size()];
	    
	    for (Message message: assignment.conversation.getMessages())
	    {
		for (DialogueAct da: message.getDialogueActs(matrix.annotator1))
		    ;
	    }
	    
	    
	    
	    
	    
	    
	    
	    
	    return null;
	}
    
    
	/**
	 * Returns list of all Assignments of the specified DialogueActDimension sorted by AssignmentId
	 */
	public List<Assignment> getAssignments(User user)
	{
		return getAssignments(0, user);
	}
	
	
	/**
	 * Returns list of all Assignments of the specified DialogueActDimension sorted by AssignmentId
	 */
	public List<Assignment> getAssignments(int datasetId, User user)
	{
		List<Assignment> list = null;
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();

		try
		{
			String query;
			
			if (datasetId == 0)
			{
				// for all the dataset
				//
				query= "FROM Assignment WHERE user = :user" +
			    	           " ORDER BY conversationId";
				list = session.createQuery(query).setEntity("user", user).list();
			} 
			else 							
			{
				// for a specific dataset
				// 
				
			    Dataset dataset = (Dataset) session.get(Dataset.class, datasetId);
				query= "FROM Assignment" +
				        " WHERE conversation.dataset = :dataset" +
						" AND user = :user"; // +
 	                    //" ORDER BY conversationId";
				
				list = session.createQuery(query).setEntity("dataset", dataset).setEntity("user", user).list();
				//list = session.createQuery(query).setInteger("datasetId", datasetId).setEntity("user", user).list();
			}

			for (Assignment assignment: list) 
			{
				Hibernate.initialize(assignment.user);
				Hibernate.initialize(assignment.conversation);
				Hibernate.initialize(assignment.conversation.assignments);
			}
			
			session.getTransaction().commit();
		}
		catch (HibernateException e)
		{
			session.getTransaction().rollback();
			throw e;
		}
		return list;
	}
		
	public List<Assignment> getAssignments()
	{
		return getAssignments(false);
	}
	
	public List<Assignment> getAssignments(boolean lazy)
	{
		List<Assignment> assignments;
		
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();

		try
		{
			assignments = session.createQuery("FROM Assignment").list();

			if (!lazy) 
			{
				for (Assignment assignment: assignments) 
				{
					Hibernate.initialize(assignment.user);
					Hibernate.initialize(assignment.conversation);					
				}
			}
			session.getTransaction().commit();
		}
		catch (HibernateException e)
		{
			session.getTransaction().rollback();
			throw e;
		}
		return assignments;	
		}
	
	public Assignment getAssignment(Conversation conversation, User user)
	{
		Assignment assignment;
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();

		try
		{
			assignment = (Assignment) session
			.createQuery("FROM AnnotationSession WHERE user = :user" +
					     "AND conversation = :conversation")
			.setEntity("user", user)
			.setEntity("conversation", conversation)
			.uniqueResult();
			// Always not lazy  
			Hibernate.initialize(assignment.user);
			Hibernate.initialize(assignment.conversation);		
			session.getTransaction().commit();
		}
		catch (HibernateException e)
		{
			session.getTransaction().rollback();
			throw e;
		}
		return assignment;
	}	

	public Assignment getAssignment(int assignmentId)
	{
		Assignment assignment;
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();

		try
		{
			assignment = (Assignment) session
			.createQuery("FROM AnnotationSession WHERE user = :user" +
					     "AND conversation = :conversation")
			.setInteger("assignmentId", assignmentId)
			.uniqueResult();
			// Always not lazy  
			Hibernate.initialize(assignment.user);
			Hibernate.initialize(assignment.conversation);		
			session.getTransaction().commit();
		}
		catch (HibernateException e)
		{
			session.getTransaction().rollback();
			throw e;
		}
		return assignment;
	}

	/**
	 * Saves a Assignment object.
	 */
	public void saveAssignment(Assignment Assignment)
	{
		Session session = HibernateUtil.getSessionFactory()
		.getCurrentSession();
		session.beginTransaction();
		try
		{
			session.saveOrUpdate(Assignment);
			session.getTransaction().commit();
		}
		catch (HibernateException e)
		{
			session.getTransaction().rollback();
			throw e;
		}
	}
	
	/**
	 * Deletes Assignment record with matching AssignmentId 
	 */
	public void deleteAssignment(int AssignmentId)
	{
		Session session = 
			HibernateUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();	
		try
		{
			Object toDelete = session.get(Assignment.class,new Integer(AssignmentId));

			if (toDelete != null) { 
				session.delete(toDelete);
			}

			session.flush();
			session.getTransaction().commit();
		}
		catch (HibernateException e)
		{
			session.getTransaction().rollback();
			throw e;
		}
	}


}
